package com.newcoin.chat.service.impl;

import com.alibaba.fastjson.JSON;
import com.newcoin.chat.beans.entity.FriendApplicationEntity;
import com.newcoin.chat.beans.entity.FriendMsgEntity;
import com.newcoin.chat.beans.vo.*;
import com.newcoin.chat.dao.FriendDao;
import com.newcoin.chat.service.FriendService;
import com.newcoin.chat.util.PinYinUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class FriendServiceImpl implements FriendService {
    @Autowired
    private FriendDao dao;

    /**
     * 根据账号或者昵称查询好友
     *
     * @param parameter
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<List<UserVo>> getFriendInfoByFriendNicknameOrAccount(String parameter) throws Exception {
        log.info("根据账号或者昵称查询好友入参parameter={}", parameter);
        ResultVo<List<UserVo>> resultVo = new ResultVo<>();
        if (parameter == null) {
            resultVo.setStatus(409);//参数为空
            resultVo.setMsg("请输入账号或者昵称");
            log.info("resultVo={}", resultVo);
            return resultVo;
        }
        List<UserVo> userVos = dao.getFriendInfoByFriendNicknameOrAccount("%" + parameter + "%");
        log.info("userVo={}", userVos);
        if (userVos == null) {
            resultVo.setStatus(408);//用户为空
            resultVo.setMsg("没有此用户");
        } else {
            resultVo.setStatus(200);
            resultVo.setMsg("查询成功");
            resultVo.setResultData(userVos);
        }
        return resultVo;
    }

    /**
     * 新增添加好友申请
     *
     * @param userId
     * @param friendId
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<String> addFriendApplicationInfo(long userId, long friendId, String remark) throws Exception {
        log.info("新增添加好友申请入参userId={},friendId={},remark={}", userId, friendId, remark);
        ResultVo<String> resultVo = new ResultVo<String>();
        int var = dao.verifyThatYouAreAlreadyFriends(userId, friendId);
        if (var > 0) {
            resultVo.setStatus(201);//201已是好友
            resultVo.setMsg("你们已经是好友啦，快去聊天吧");
            log.info("resultVo={}", resultVo);
            return resultVo;
        }
        FriendApplicationEntity friendApplicationEntity = new FriendApplicationEntity();
        friendApplicationEntity.setFromUser(userId);
        friendApplicationEntity.setToUser(friendId);
        friendApplicationEntity.setRemark(remark);
        friendApplicationEntity.setState(0);
        log.info("friendApplicationEntity={}", friendApplicationEntity);
        int row = dao.addFriendApplicationInfo(friendApplicationEntity);
        log.info("新增添加好友申请insert返回 row={}", row);
        if (row != 1) {
            resultVo.setStatus(509);//申请添加好友失败
            resultVo.setMsg("申请失败");
        } else {
            resultVo.setStatus(200);//申请添加好友成功
            resultVo.setMsg("申请成功,等待对方同意");
        }
        log.info("resultVo={}", resultVo);
        return resultVo;
    }

    /**
     * 是否有新的好友申请消息
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<Boolean> isThereANewFriendApplication(long userId) throws Exception {
        log.info("是否有新的好友申请消息入参 userId={}", userId);
        ResultVo<Boolean> resultVo = new ResultVo<>();
        resultVo.setStatus(200);
        int count = dao.isThereANewFriendApplication(userId);
        if (count > 0)
            resultVo.setResultData(true);
        else
            resultVo.setResultData(false);
        return resultVo;
    }

    /**
     * 获取最近10条的好友申请
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<List<FriendApplicationEntity>> getFriendApplicationList(long userId) throws Exception {
        log.info("获取3天内的好友申请入参 userId={}", userId);
        ResultVo<List<FriendApplicationEntity>> resultVo = new ResultVo<>();
        List<FriendApplicationEntity> friendApplicationEntityList = dao.getFriendApplicationListById(userId);
        log.info("friendApplicationEntityListCount={}", friendApplicationEntityList.size());
        resultVo.setStatus(200);
        resultVo.setMsg("获取成功");
        resultVo.setResultData(friendApplicationEntityList);
        new Thread(() -> {
            friendApplicationEntityList.forEach(e -> {
                if (e.getState() == 0) {
                    int row = dao.updateFriendApplicationStateById(e.getId(), 1);
                    log.info("更新的申请的id={},row={}", e.getId(), row);
                }
            });
        }).start();
        return resultVo;
    }

    /**
     * 通过或拒绝朋友申请
     *
     * @param friendApplicationId
     * @param state
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> passOrRejectFriendApplication(long friendApplicationId, int state) throws Exception {
        log.info("通过或拒绝朋友申请入参friendApplicationId={},state={}", friendApplicationId, state);
        ResultVo<String> resultVo = new ResultVo<>();
        int row = dao.updateFriendApplicationStateById(friendApplicationId, state);
        log.info("更改好友申请状态row={}", row);
        if (row != 1) {
            resultVo.setStatus(507);//通过或者拒绝好友失败
            if (state == 2)
                resultVo.setMsg("接收失败");
            else if (state == 3)
                resultVo.setMsg("拒绝失败");
            log.info("resultVo={}", resultVo);
            return resultVo;
        } else {
            if (state == 2) {
                FriendApplicationEntity entity = dao.getFriendApplicationById(friendApplicationId);
                log.info("entity={}", entity);
                if (entity == null)
                    throw new RuntimeException("获取信息失败");
                int row1 = dao.addFriend(entity.getToUser(), entity.getFromUser());//toUser是被申请人 也是点击同意或者拒绝的人
                row1 = row1 + dao.addFriend(entity.getFromUser(), entity.getToUser());
                log.info("添加好友返回<成功为2> row1={}", row1);
                if (row1 != 2)
                    throw new RuntimeException("添加好友失败");
                resultVo.setStatus(200);
                resultVo.setMsg("添加好友成功");
            } else if (state == 3) {
                resultVo.setStatus(200);
                resultVo.setMsg("拒绝完成");
            }
        }
        log.info("resultVo={}", resultVo);
        return resultVo;
    }

    /**
     * 删除好友
     *
     * @param userId
     * @param friendId
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> deleteFriend(long userId, long friendId) throws Exception {
        log.info("删除好友入参 userId={},friendId={}", userId, friendId);
        ResultVo<String> resultVo = new ResultVo<>();
        int row = dao.deleteFriend(userId, friendId);
        row = row + dao.deleteFriend(friendId, userId);
        log.info("删除好友 row={}", row);
        if (row != 2)
            throw new RuntimeException("删除好友失败");
        resultVo.setStatus(200);
        resultVo.setMsg("删除好友成功");
        return resultVo;
    }

    /**
     * 打开或关闭阅后即焚
     *
     * @param userId
     * @param friendId
     * @param state
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> openOrCloseAfterReadingIncineration(long userId, long friendId, int state) throws Exception {
        log.info("打开或关闭阅后即焚入参 userId={},friendId={},state={}", userId, friendId, state);
        ResultVo<String> resultVo = new ResultVo<>();
        int row = dao.openOrCloseAfterReadingIncineration(userId, friendId, state);
        row = row + dao.openOrCloseAfterReadingIncineration(friendId, userId, state);
        if (row != 2)
            throw new RuntimeException("开启或者关闭阅后即焚失败");

        FriendMsgEntity friendMsgEntity = new FriendMsgEntity();
        friendMsgEntity.setFromUser(userId);
        friendMsgEntity.setToUser(friendId);
        friendMsgEntity.setContent(burnAfterReadingStatusSwitch(state));
        friendMsgEntity.setIsHaveRead(0);
        friendMsgEntity.setIsSystemType(1);
        friendMsgEntity.setType("text");
        friendMsgEntity.setState(0);
        log.info("开启或者关闭阅后即焚系统消息 friendMsgEntity={}", friendMsgEntity);
        int row1 = dao.addNewSystemMessages(friendMsgEntity);
        log.info("开启或者关闭阅后即焚插入系统消息 row1={}", row1);
        if (row1 != 1)
            throw new RuntimeException("开启或者关闭阅后即焚失败");
        resultVo.setMsg(state == 0 ? "关闭成功" : "开启成功");
        resultVo.setStatus(200);
        log.info("resultVo={}", resultVo);
        return resultVo;
    }

    /**
     * 获取所有的好友申请信息
     *
     * @param userId
     * @param page
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<FriendApplicationVo> getAllFriendApplicationMessages(long userId, int page) throws Exception {
        log.info("获取所有的好友申请信息入参 userId=#{},page={}", userId, page);
        ResultVo<FriendApplicationVo> resultVo = new ResultVo<>();
        page = (page - 1) * 10;
        PageParamVo pageParamVo = new PageParamVo();
        pageParamVo.setPage(page);
        pageParamVo.setUserId(userId);
        log.info("pageParamVo={}", pageParamVo);
        List<FriendApplicationEntity> list = dao.getAllFriendApplicationListById(pageParamVo);
        log.info("listCount={}", list.size());
        int count = dao.getAllFriendApplicationCount(userId);
        log.info("count={}", count);
        FriendApplicationVo friendApplicationVo = new FriendApplicationVo();
        if (count <= 10) {
            friendApplicationVo.setTotalPages(1);
            friendApplicationVo.setCurrentPage(1);
        } else {
            friendApplicationVo.setTotalPages(count % 10 == 0 ? count / 10 : count / 10 + 1);
            friendApplicationVo.setCurrentPage(page / 10 + 1);
        }
        friendApplicationVo.setApplicationList(list);
        log.info("friendApplicationVo={}", friendApplicationVo);
        resultVo.setStatus(200);
        resultVo.setMsg("查询成功");
        resultVo.setResultData(friendApplicationVo);
        log.info("resultVo={}", resultVo);
        return resultVo;
    }

    /**
     * 通讯录列表
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<Map<String, Object>> getContactList(long userId) throws Exception {
        log.info("通讯录列表入参 userId={}", userId);
        ResultVo<Map<String, Object>> resultVo = new ResultVo<>();
        resultVo.setStatus(200);
        List<UserVo> friendList = dao.getContactList(userId);
        log.info("friendListCount={}", friendList.size());
        Map<String, Object> map = PinYinUtil.sort(friendList);
        log.info("map={}", JSON.toJSONString(map));
        resultVo.setMsg("查询成功");
        resultVo.setResultData(map);
        log.info("resultVo={}", resultVo);
        return resultVo;
    }

    /**
     * 获取朋友发来的消息（离线）
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<List<FriendOfflineMsgVo>> getFriendOfflineMsg(long userId) throws Exception {
//        log.info("获取朋友发来的消息（离线）入参 userId={}");
//        List<FriendOfflineMsgVo> list = dao.getFriendOfflineMsg(userId);
//        log.info("list={}", list);
//        ResultVo<List<FriendOfflineMsgVo>> resultVo = new ResultVo<>();
//        resultVo.setResultData(list);
//        resultVo.setStatus(200);
//        log.info("resultVo={}", resultVo);
//        return resultVo;
        return null;
    }

    /**
     * 获取聊天消息
     *
     * @param userId
     * @param friendId
     * @param page
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<List<FriendMsgEntity>> getFriendMsg(long userId, long friendId, int page) throws Exception {
        log.info("获取聊天消息userId={},friendId={},page={}", userId, friendId, page);
        page = (page - 1) / 10;

        return null;
    }

    /**
     * 获取用户信息
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<UserVo> getUserInfo(Long userId) throws Exception {
        log.info("获取用户信息userId={}", userId);
        UserVo userVo = dao.getUserInfoById(userId);
        log.info("userVo={}", userVo);
        ResultVo<UserVo> resultVo = new ResultVo<>();
        resultVo.setStatus(200);
        resultVo.setResultData(userVo);
        log.info("resultVo={}", resultVo);
        return resultVo;
    }

    /**
     * 获取与朋友的阅后即焚状态
     *
     * @param userId
     * @param friendId
     * @return
     */
    @Override
    public ResultVo<Integer> getAfterReadingIncinerationState(long userId, long friendId) throws Exception {
        log.info("获取与朋友的阅后即焚状态 userId={},friendId={}", userId, friendId);
        Integer state = dao.getAfterReadingIncinerationState(userId, friendId);
        ResultVo<Integer> resultVo = new ResultVo();
        resultVo.setMsg("成功");
        resultVo.setStatus(200);
        resultVo.setResultData(state);
        return resultVo;
    }

    /***
     * 获取离线消息
     * @param userId
     * @param friendId
     * @return
     * @throws Exception
     */
    @Override
    public ResultVo<List<FriendOfflineMsgVo>> getOfflineMessage(Long userId, Long friendId) throws Exception {
        log.info("获取离线消息入参 userId={},friendId={}", userId, friendId);
        Map<String, Long> map = dao.getFriendOfflineMsg(userId, friendId);
        List<FriendOfflineMsgVo> list = null;
        if (map != null) {
            list = dao.getFriendOfflineMsgVo(Long.valueOf(String.valueOf(map.get("last_message_id"))), userId, friendId);
        }
        ResultVo<List<FriendOfflineMsgVo>> resultVo = new ResultVo<>();
        resultVo.setStatus(200);
        resultVo.setMsg("成功");
        resultVo.setResultData(list);
        List<FriendOfflineMsgVo> finalList = list;
        new Thread(() -> {
            dao.updateOfflineMsg(userId, friendId);
            for (FriendOfflineMsgVo f : finalList) {
                dao.updateMsgIsHaveReadStatus(f.getId());
            }
        }).start();
        return resultVo;
    }

    /**
     * 阅后即焚状态选择器
     *
     * @param state
     * @return
     */
    private String burnAfterReadingStatusSwitch(int state) {
        switch (state) {
            case 0:
                return "关闭阅后即焚";
            case 1:
                return "开启阅后即焚";
            case 2:
                return "开启10秒后焚毁";
            case 3:
                return "开启5分钟后焚毁";
            case 4:
                return "开启1小时后后焚毁";
            case 5:
                return "开启24小时后焚毁";
            default:
                return "关闭阅后即焚";
        }
    }


}
